package com.bruce.asurada.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import com.bruce.asurada.common.Result;
import com.bruce.asurada.common.constants.TokenConstants;
import com.bruce.asurada.config.SsoProperties;
import com.bruce.asurada.dto.LoginResponseDto;
import com.bruce.asurada.common.dto.* ;
import com.bruce.asurada.service.SsoClientService;
import com.bruce.asurada.util.HttpClientUtil;

import org.springframework.http.HttpHeaders;
import java.util.HashMap;
import java.util.Map;

import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class SsoClientServiceImpl implements SsoClientService {

    @Autowired
    private SsoProperties ssoProperties;

    @Autowired
    private HttpClientUtil httpClientUtil;

    /**
     * 获取登录授权码
     */
    public String getAuthCode(UserLoginDto loginDto) throws Exception {
        String authCodeUrl = ssoProperties.getServer().getGenerateAuthCodeUrl();
            
        // 构建请求参数
        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
        params.add("account", loginDto.getAccount());
        params.add("password", loginDto.getPassword());
        params.add("clientId", ssoProperties.getClient().getId());
            
            // 将表单参数转换为JSON对象
        Map<String, String> jsonParams = new HashMap<>();
        params.forEach((key, value) -> {
            if (value != null && !value.isEmpty()) {
                jsonParams.put(key, value.get(0));
            }
        });
            
        Result<String> result =  httpClientUtil.post(
            authCodeUrl,
            jsonParams,
            new ParameterizedTypeReference<Result<String>>() {}
        );
        if(null == result|| !result.isSuccess()){
            String message = null != result ? result.getMessage(): "登录失败";
            throw new RuntimeException(message);
        }
        return result.getData();
    }


    /**
     * 获取令牌
     * @param loginDto
     * @return
     */
    @Override
    public TokenDTO getToken(UserLoginDto loginDto,String authCode)throws Exception{
         String tokenUrl = ssoProperties.getServer().getTokenUrl();
            
        // 构建请求参数
         MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
         params.add("account", loginDto.getAccount());
         params.add("password", loginDto.getPassword());
         params.add("authCode", authCode) ;
         params.add("clientId", ssoProperties.getClient().getId());
            
        // 将表单参数转换为JSON对象
        Map<String, String> jsonParams = new HashMap<>();
        params.forEach((key, value) -> {
            if (value != null && !value.isEmpty()) {
                jsonParams.put(key, value.get(0));
             }
        });
            
        Result<TokenDTO> result = httpClientUtil.post(
            tokenUrl,
            jsonParams,
            new ParameterizedTypeReference<Result<TokenDTO>>() {}
        );
        if(null == result|| !result.isSuccess()){
            String message = null != result ? result.getMessage(): "获取令牌失败";
            throw new RuntimeException(message);
        }
        return result.getData();
    }

    @Override
    public Result<Void> sendPhoneCode(String phone) {
        try{
             // 构建请求参数
            String sendPhoneCodeUrl = ssoProperties.getServer().getPhonecodeUrl();
            MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
            params.add("phone", phone);
            params.add("clientId", ssoProperties.getClient().getId());
            
            // 将表单参数转换为JSON对象
            Map<String, String> jsonParams = new HashMap<>();
            params.forEach((key, value) -> {
                if (value != null && !value.isEmpty()) {
                    jsonParams.put(key, value.get(0));
                }
            });
            
            Result<Void> result = httpClientUtil.post(
            sendPhoneCodeUrl,
            jsonParams,
            new ParameterizedTypeReference<Result<Void>>() {}
             );
            if (result != null && result.isSuccess()) {
                log.info("发送验证码请求成功: {}", phone);
            }
            return result;
        }catch (Exception e){
            log.error("发送验证码请求失败: {}", e.getMessage(), e);
             return Result.error("发送验证码失败: " + e.getMessage());
        }
    }

    /**
     * 验证码登录
     */
    public Result<LoginResponseDto> loginByPhoneAndCode(PhoneCodeLoginDTO loginDto){
        try {
            String authCodeUrl = ssoProperties.getServer().getGenerateAuthCodeUrl();
            
            // 构建请求参数
            MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
            params.add("phone", loginDto.getPhone());
            params.add("phoneCode", loginDto.getPhoneCode());
            params.add("clientId", ssoProperties.getClient().getId());
            
            // 将表单参数转换为JSON对象
            Map<String, String> jsonParams = new HashMap<>();
            params.forEach((key, value) -> {
                if (value != null && !value.isEmpty()) {
                    jsonParams.put(key, value.get(0));
                }
            });
            
            Result<LoginResponseDto> result = httpClientUtil.post(authCodeUrl, jsonParams,new ParameterizedTypeReference<Result<LoginResponseDto>>() {});
            if (result != null && result.isSuccess()) {
                log.info("验证码登录成功: {}", loginDto.getPhone());
            }
            
            return result;
        } catch (Exception e) {
            log.error("验证码登录请求失败: {}", e.getMessage(), e);
            return Result.error("验证码登录失败: " + e.getMessage());
        }
    }

    /**
     * 验证令牌
     */
    public UserInfoDto verifyToken(String token) throws Exception{
        String verifyUrl = ssoProperties.getServer().getVerifyUrl();
        // 构建请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setBearerAuth(token);

        Result<UserInfoDto> result = httpClientUtil.get(verifyUrl, headers,new ParameterizedTypeReference<Result<UserInfoDto>>() {}) ;
        if(null == result|| !result.isSuccess()){
            String message = null != result ? result.getMessage(): "验证令牌失败";
            throw new RuntimeException(message);
        }            
        return result.getData();
    }

    /**
     * 检查登录状态
     */
    public Result<Boolean> checkLoginStatus(String token) {
        try {
            String checkUrl = ssoProperties.getServer().getCheckUrl();
            
            // 构建请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setBearerAuth(token);
            
            return httpClientUtil.get(checkUrl,headers,new ParameterizedTypeReference<Result<Boolean>>() {}) ;
        } catch (Exception e) {
            log.error("检查登录状态失败: {}", e.getMessage(), e);
            return Result.success("登录状态检查完成", false);
        }
    }

    /**
     * 用户登出
     */
    @Override
    public void logout(TokenDTO tokenDTO) throws Exception {
        String logoutUrl = ssoProperties.getServer().getLogoutUrl();
        // 构建请求头
        HttpHeaders headers = new HttpHeaders();
        headers.set(TokenConstants.ACCESS_TOKEN_HEADER_NAME, tokenDTO.getAccessToken());
        headers.set(TokenConstants.REFRESH_TOKEN_HEADER_NAME, tokenDTO.getRefreshToken());
        headers.set(TokenConstants.IM_SESSION_TOKEN_HEADER_NAME, tokenDTO.getImSessionToken()) ;
        headers.set(TokenConstants.IM_ACCESS_TOKEN_HEADER_NAME, tokenDTO.getImAccessToken());
        
        Result<Void> result = httpClientUtil.get(logoutUrl, headers, new ParameterizedTypeReference<Result<Void>>() {});
        if (null == result || !result.isSuccess()) {
            String message = null != result ? result.getMessage() : "登出失败";
            throw new RuntimeException(message);
        }
    }

    /**
     * 刷新令牌
     */
    public TokenDTO refreshToken(String refreshToken) throws Exception{
        String refreshUrl = ssoProperties.getServer().getRefreshUrl();
            
        // 构建请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setBearerAuth(refreshToken);
        Result<TokenDTO> result = httpClientUtil.get(refreshUrl, headers, new ParameterizedTypeReference<Result<TokenDTO>>() {});
        if (null == result || !result.isSuccess()) {
            String message = null != result ? result.getMessage() : "刷新令牌失败";
            throw new RuntimeException(message);
        }
        return result.getData();
    }

}